package com.utils.catche;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

/**
 * 加密工具类
 * @author: dingjiejun
 * @version: 1.0
 * @date: 2017/3/26
 */
public class EncryptUtils {

    public static final String ALGORITHM = "DES";
    public static final String ENCODEING = "UTF-8";
    public static final String DESKEY = "77616e6461313139";
    public static final String CIPHER = "DES/ECB/PKCS5Padding";

    /**
     * 将十六进制数字字符串转成字节流
     *
     * @param hexStr 十六进制数字字符串
     * @return 字节流
     */
    public static byte[] hexStrToByte(String hexStr) {
        try {
            return Hex.decodeHex(hexStr.toCharArray());
        } catch (DecoderException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将字节流转成十六进制数字字符串
     *
     * @param source 字节流
     * @return 十六进制数字字符串
     */
    public static String byteToHexStr(byte[] source) {
        return new String(Hex.encodeHex(source));
    }

    /**
     * DES 加密
     *
     * @param source 源数据
     * @param keyStr 加密key
     * @return 加密后的目标数据
     * @throws UnsupportedEncodingException
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     */
    public static String encode(String source, String keystr) {
        try {
            Cipher cipher = Cipher.getInstance(CIPHER);
            SecretKey key = new SecretKeySpec(hexStrToByte(keystr), ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] keyhex = cipher.doFinal(source.getBytes(ENCODEING));
            return byteToHexStr(keyhex);
        } catch (Exception e) {
            throw new RuntimeException("key无效");
        }

    }

    public static String encode(String source) {
        return encode(source, DESKEY);

    }

    /**
     * 随机DES加密
     * @param source
     * @return
     */
    public static String randomEncode(String source) {
        try {
            Cipher cipher = Cipher.getInstance(CIPHER);
            KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM);
            generator.init(new SecureRandom());
            SecretKey key = generator.generateKey();
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] keyhex = cipher.doFinal(source.getBytes(ENCODEING));
            return byteToHexStr(keyhex);
        } catch (Exception e){
            throw new RuntimeException("key无效");
        }

    }

    /**
     * DES 解密
     *
     * @param dest 已加密的目标数据
     * @return 解密后的源数据
     * @throws InvalidKeyException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     */
    public static String decode(String dest, String keystr) {
        try {
            Cipher cipher = Cipher.getInstance(CIPHER);
            SecretKey key = new SecretKeySpec(hexStrToByte(keystr), ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] desthex = cipher.doFinal(hexStrToByte(dest));
            return new String(desthex, ENCODEING);
        } catch (Exception e){
            throw new RuntimeException("key无效",e);
        }
    }

    public static String decode(String dest) {
        return decode(dest, DESKEY);

    }

    /**
     * 根据种子字符串生成密钥
     *
     * @param seed 种子字符串
     * @return 密钥
     * @throws NoSuchAlgorithmException
     * @throws UnsupportedEncodingException
     */
    public static SecretKey generateKey(String seed) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM);
        generator.init(new SecureRandom(seed.getBytes(ENCODEING)));
        return generator.generateKey();
    }

    public static SecretKey generateKey() throws NoSuchAlgorithmException, UnsupportedEncodingException {
        KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM);
        generator.init(new SecureRandom());
        return generator.generateKey();
    }

    public static String generateKeyStr() {
        try {
            return byteToHexStr(generateKey().getEncoded());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("算法无效");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("编码无效");
        }
    }

    /**
     * md5加密
     *
     * @param str
     * @return
     * @throws Exception
     */
    public static String md5Digest(String str) {
        MessageDigest md;
        try {
            md = MessageDigest.getInstance("md5");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return "";
        }
        StringBuilder sb = new StringBuilder();
        md.update(str.getBytes());
        byte[] byteArr = md.digest();
        String tmp;
        for (byte aByteArr : byteArr) {
            tmp = Integer.toHexString(aByteArr & 0XFF);
            if (tmp.length() == 1) {
                sb.append("0");
            }
            sb.append(tmp);
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        try {
            //System.out.print(byteToHexStr(SecurityEncodeHelper.generateKey().getEncoded()));
            //String a1 = md5Digest("1461684526956");
            //String a2 = md5Digest("111111");
            //System.out.println(a1);
            //System.out.println(a2);
            //String a3 = md5Digest(a1+a2);
            //System.out.println(a3);

            String a4 = encode("wonders12321212");
            System.out.println(a4);
            String a5 = decode(a4);

            System.out.println(a5);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}
